package pay.portal;

import java.util.HashMap;
import java.util.Map;

import org.apache.http.client.utils.URIBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import pay.base.BaseCtrl;
import pay.base.ResponseBase;
import pay.common.ResultCode;
import pay.entity.ApiSecret;
import pay.entity.SysUser;
import pay.portal.web.message.BalanceMsg;
import pay.portal.web.message.UserMsg;
import pay.service.IApiSecret;
import pay.service.IErrorLogJPA;
import pay.service.IFYResultCode;
import pay.service.IOrderHelper;
import pay.service.IOrderJpa;
import pay.service.ITrade;
import pay.service.sys.ISysUser;
import pay.utils.BalanceUtils;
import pay.utils.DateUtil;
import pay.utils.EncryptDecryptUtils;
import pay.utils.FYApiUtil;
import pay.utils.MapSortUtil;
import pay.utils.SecurityUtils;
import pay.utils.StringHelper;
import pay.utils.XmlUtils;

/**
 * 查询账户余额
 *
 * @author jeff
 */
@Controller
@EnableAutoConfiguration
@RequestMapping(value = BaseCtrl.App)
public class CheckBalanceCtrl extends BaseCtrl {

    private Logger logger = LoggerFactory.getLogger(CheckBalanceCtrl.class);

    /**
     * 商户代码，从配置文件中读取
     */
    @Value("${fy.mchntCd}")
    private String mchnt_cd;

    @Value("${server.scheme}")
    private String serverScheme;

    @Value("${fy.goldAccount.pathBaseUrl}")
    private String pathBaseUrl;// 测试环境为/jzh 生产无。
    // /**
    // * 商户密钥，从配置文件中读取
    // */
    // @Value("${fy.Secret}")
    // private String secret;

    @Value("${server.url}")
    private String serverUrl;

    @Autowired
    private IApiSecret apiSecretService;

    @Autowired
    private ITrade tradeService;

    /**
     * 金账户baseURl，从配置文件中读取
     */
    @Value("${fy.goldAccount.baseUrl}")
    private String jzhBaseUrl;

    @Autowired
    private IFYResultCode fyResultCodeService;

    @Autowired
    private ISysUser sysUserService;

    @Autowired
    private IErrorLogJPA errorLogJPA;
    @Autowired
    private IOrderHelper orderHelperService;
    
    @Autowired
    private IOrderJpa OrderJPAService;

    /*
     * 查询客户账户余额
     */
    @ResponseBody
    @RequestMapping(value = "/checkBalance", method = RequestMethod.POST)
    public ResponseBase<BalanceMsg> checkBalance(@RequestBody UserMsg req) {
        ResponseBase<BalanceMsg> resp = new ResponseBase<>();

        if (req == null) {
            resp.setResultCode(ResultCode.PARAM_ERROR.getCode());
            String errorMsg = ResultCode.PARAM_ERROR.getMsg();
            resp.setMsg(errorMsg);
            logger.error("请求信息参数错误。");
            return resp;
        }

        Long userId = req.getUserId();

        String sign = req.getSign();

        String apiKey = req.getApiKey();

        logger.info("查询客户账户余额 入参   userId={},   sign={}, apiKey={}", userId,
                sign, apiKey);

        logger.info("金账户查询客户账户余额 userId ={}", req.getUserId());


        // 01.测试入参是否合乎要求
        if (userId == null || StringHelper.isEmpty(sign)
                || StringHelper.isEmpty(apiKey)) {
            resp.setResultCode(ResultCode.PARAM_ERROR.getCode());
            String errorMsg = ResultCode.PARAM_ERROR.getMsg();
            resp.setMsg(errorMsg);
            logger.info("请求信息参数错误。");
            return resp;
        }

        // 02.测试用户是否存在
        SysUser user = sysUserService.findById(userId);
        if (user == null) {
            resp.setMsg("该用户不存在。userId ={}" + userId);
            resp.setResultCode(ResultCode.PARAM_ERROR.getCode());
            return resp;
        }

        // 03.判断签名是否正常
        ApiSecret apiSecret = apiSecretService.findByApikey(apiKey);
        String scretStr = "";

        if (apiSecret != null) {
            scretStr = apiSecret.getApiSecret();
            logger.info("scretStr = " + scretStr);
        }

        Map<String, String> map = getRequestMap(userId, sign, apiKey);
        
        logger.info("start send message to fy *******************");
        boolean checkResult = EncryptDecryptUtils.validateSignByMap(scretStr, map);
        logger.info("get  message to fy *******************");

        if (!checkResult) {
            logger.info("验证失败");
            String errorMsg = ResultCode.IREECT_SIGN.getMsg();
            resp.setMsg(errorMsg);
            resp.setResultCode(ResultCode.IREECT_SIGN.getCode());
            return resp;
        }

        // 交易日期
        String mchnt_txn_dt = DateUtil.longToShortDate02(System
                .currentTimeMillis());

        // 待查询的登录帐户
        String cust_no = user.getName();

        // 流水号
        String mchnt_txn_ssn = cust_no
                + String.valueOf(System.currentTimeMillis());
        // 签名
        String signature = null;

        String allUrl = cust_no + "|" + mchnt_cd + "|" + mchnt_txn_dt + "|"
                + mchnt_txn_ssn;

        logger.info("金账户查询客户账户余额的明文={}" + allUrl);

        SecurityUtils.initPrivateKey();
        SecurityUtils.initPublicKey();

        signature = SecurityUtils.sign(allUrl);

        String pathUrl = pathBaseUrl + "/BalanceAction.action";
        URIBuilder builder = new URIBuilder().setScheme("https")
                .setHost(jzhBaseUrl).setPath(pathUrl);

        Map<String, String> trimmedParams = new HashMap<>();

        trimmedParams.put("mchnt_cd", mchnt_cd);
        trimmedParams.put("mchnt_txn_ssn", mchnt_txn_ssn);
        trimmedParams.put("mchnt_txn_dt", mchnt_txn_dt);
        trimmedParams.put("cust_no", cust_no);
        trimmedParams.put("signature", signature);

        // 获取冻结笔数
        logger.info("start getDJ order message *******************");
        
        //Long cf_account = orderHelperService.getDJOrderAccount(userId);
        
        Long cf_account  = OrderJPAService.getDJOrderAccount(userId);
        
        logger.info("end getDJ order  message *******************");
        
        logger.info("冻结的笔数是：" + cf_account);

        try {
            String result = FYApiUtil.doPost(builder, trimmedParams);

            BalanceMsg msg = new BalanceMsg();

            String ct_balance = XmlUtils.getVal(result, "ct_balance");
            msg.setCt_balance(BalanceUtils.getFYVal(ct_balance));

            String ca_balance = XmlUtils.getVal(result, "ca_balance");
            msg.setCa_balance(BalanceUtils.getFYVal(ca_balance));

            String cf_balance = XmlUtils.getVal(result, "cf_balance");
            msg.setCf_balance(BalanceUtils.getFYVal(cf_balance));

            String cu_balance = XmlUtils.getVal(result, "cu_balance");
            msg.setCu_balance(BalanceUtils.getFYVal(cu_balance));

            msg.setCf_account(cf_account);
            resp.setResultCode(ResultCode.SUCC.getCode());
            resp.setResult(msg);

        } catch (Exception e) {
            logger.error("查询用户余额异常， 用户id={}, e:{}", req.getUserId() , e);
        }
        
        logger.info("查询用户余额 will return *******************");
        return resp;
    }

    private Map<String, String> getRequestMap(Long userId, String sign,
                                              String apiKey) {

        Map<String, String> map = new HashMap<String, String>();
        map.put("userId", userId.toString());
        map.put("sign", sign);
        map.put("apiKey", apiKey);
        map = MapSortUtil.sortMapByKey(map);
        return map;

    }

}
